#include "gp_subboard_ctl.h"
#include "sock_msg_ctl.h"
#include "gp_layout_map.h"
#include "stdio.h"
#include "string.h"
#include "../lua/action_msg.h"
#include "resource_manage.h"
#include <unistd.h>
#include "../data_proc/board_data_proc.h"

const int sidSmoothArr[5] = {27,26,25,24,23};//{25,27,24,26,23};

/*         25.A.3
   27.B.1  24.C.4
   26.D.2  23.E.5
*/

/*
0->4
1->3

*/

int magnetCtlForScanCode(int scanId, int isLock)
{
    int actSuccess = 0;
    if(scanId < 0 || scanId > 1)
    {
        return actSuccess;
    }
    int drawerIdArr[4] = {0};
    int numToCtl = 0;
    if(scanId == BARCODE_SCAN_PURIFY_REAGENT)
    {// for purify reagent scan
        drawerIdArr[0] = I_DRAWER_PURIFY_REAGENT1;
        drawerIdArr[1] = I_DRAWER_PURIFY_REAGENT2;
        numToCtl = 2;
    }
    else if(scanId == BARCODE_SCAN_SAMPLE)
    {//for sample scan
        drawerIdArr[0] = I_DRAWER_SAMPLE1;
        drawerIdArr[1] = I_DRAWER_SAMPLE2;
        drawerIdArr[2] = I_DRAWER_SAMPLE3;
        drawerIdArr[3] = I_DRAWER_SAMPLE4;
        numToCtl = 4;
    }
    else if(scanId == BARCODE_SCAN_PCR_REAGENT)
    {
        drawerIdArr[0] = I_DRAWER_PCR_BOARD;
        drawerIdArr[1] = I_DRAWER_PCR_REAGENT1;
        drawerIdArr[2] = I_DRAWER_PCR_REAGENT2;
        numToCtl = 3;        
    }
    else if(scanId == BARCODE_SCAN_CLEAN_REAGENT)
    {
        drawerIdArr[0] = I_DRAWER_DP8TIPS1;
        drawerIdArr[1] = I_DRAWER_DP8TIPS2;
        numToCtl = 2;        
    }


    drawer_lock_param drawerLockParam;
    memset(&drawerLockParam,0,sizeof(drawer_lock_param));
    drawerLockParam.isToLock = (isLock==0)?0:1;
    while(numToCtl>0)
    {
        drawerLockParam.drawerId = drawerIdArr[numToCtl-1];
        actSuccess = drawerLockCtl(&drawerLockParam,DRAWER_LOCK,1000);
        if(actSuccess!=1)
        {
            break;
        }
        numToCtl--;
    }

    return actSuccess;
}

void subboardActFunc(void * paramIn,void * actResultOut)
{
    if(!paramIn || !actResultOut)
    {
        return;
    }
    printf("enter in subboardActFunc\n");
    act_msg_node * pstActMsg = (act_msg_node *)paramIn;
    int actSuccess = 0;
    unsigned char * ptrData = (unsigned char *)(pstActMsg->paramData);
    
    if(pstActMsg->msgHead.actType == ACT_SCANCODE_CTL)
    {
        scancode_param stScanCodeParam;
        
        int chanNum = 0;
        memcpy(&chanNum,ptrData,sizeof(int));
        ptrData += sizeof(int);

        int isStart = 0;
        memcpy(&isStart,ptrData,sizeof(int));
        ptrData += sizeof(int);

        stScanCodeParam.chanNum = chanNum;
        stScanCodeParam.isStart = isStart;

        printf("ACT_SCANCODE_CTL, chanNum:%d,isStart:%d\n",chanNum, isStart);

        actSuccess = ScancodeCtl(&stScanCodeParam,SCANCODE_CTL,1000);

        if(actSuccess==1)
        {
            printf("ACT_SCANCODE_CTL, magnet ctl for scancode\n");
            actSuccess = magnetCtlForScanCode(chanNum, isStart?0:1);
        }
        else
        {
            printf("scancode failed to start\n");
        }        

    }
    else if(pstActMsg->msgHead.actType == ACT_DJ_CLEAN_CTL)
    {
        djLiquidCtl djCleanParam;
        memset(&djCleanParam,0,sizeof(djLiquidCtl));
        djCleanParam.chanNum = pstActMsg->msgHead.paramType;

        if(pstActMsg->msgHead.moduleType == MODULE_DJ_QPCR)
        {
            djCleanParam.chanNum += 16;
        }
        int isOpen = 0;
        memcpy(&isOpen,ptrData,sizeof(int));
        djCleanParam.paramType = isOpen;

        actSuccess = djCleanCtl(&djCleanParam,SYSCTL_LIQUID,1000);
    }
    else if(pstActMsg->msgHead.actType == ACT_DRAWER_CTL)
    {
        drawer_lock_param drawerLockParam;
        memset(&drawerLockParam,0,sizeof(drawer_lock_param));
        drawerLockParam.drawerId = pstActMsg->msgHead.paramType;
        int isToLock = 0;

        memcpy(&isToLock,ptrData,sizeof(int));
        drawerLockParam.isToLock = (isToLock==0)?0:1;

        actSuccess = drawerLockCtl(&drawerLockParam,DRAWER_LOCK,1000);
    }
    else if(pstActMsg->msgHead.actType == ACT_TEMPERATURE_READ)
    {
        temp_read_param tempReadParam;
        memset(&tempReadParam,0,sizeof(temp_read_param));
        int boardId = 0;
        int opcode = PURIFY_TEMPERATURE;
        if(pstActMsg->msgHead.moduleType == MODULE_SHAKE)
        {
            boardId = PURIFICATION_BOARD;
            opcode = PURIFY_TEMPERATURE;

        }
        else if(pstActMsg->msgHead.moduleType == MODULE_QPCR1)
        {
            boardId = QPCR_CTRL_BOARD;
        }
        else if(pstActMsg->msgHead.moduleType == MODULE_QPCR2)
        {
            boardId = QPCR_CTRL_BOARD_1;
        }

        tempReadParam.chanNum = pstActMsg->msgHead.paramType;
        memcpy(&tempReadParam.isStart,pstActMsg->paramData,sizeof(int));

        memcpy(&tempReadParam.interv,(char*)(pstActMsg->paramData) + sizeof(int),sizeof(int));
        
        actSuccess = readTempCtl(&tempReadParam,boardId,opcode, 2000);
     
    }
    else if(pstActMsg->msgHead.actType == ACT_SHAKE_CTL)
    {
        int chanNum = pstActMsg->msgHead.paramType;
        int isStart = 0;
        char * pData = (char *)pstActMsg->paramData;

        memcpy(&isStart,pData,sizeof(int));

        if(chanNum>=0 && chanNum <5)
        {//for magnet smooth motor.
            
            move_param moveParam;
            memset(&moveParam,0,sizeof(move_param));
            if(isStart)
            {
                moveParam.pos = MAGNET_SMOOTH_POS;
            }
            else
            {
                moveParam.pos = 0;
            }
            moveParam.dec_speed = 8000;
            moveParam.inc_speed = 8000;
            moveParam.speed = 4000;
            moveParam.sid = sidSmoothArr[chanNum];

            actSuccess = uimMoveAct_multi(&moveParam,1,10000);             

        }
        else if(chanNum>=16 && chanNum<32)
        {//for shake start or stop
            int chanNumReal = chanNum - 16;
            purifyCtl shakeCtlData;
            shakeCtlData.chanNum = chanNumReal;
            shakeCtlData.paramType = PURIFY_SHAKE;
            
            pData += sizeof(int);

            int duration = 0;
            memcpy(&duration,pData,sizeof(int));

            shakeCtlData.duration = duration; 

            unsigned int opcode = CENTRE_START;
            if(isStart == 0)
            {
                opcode = CENTRE_STOP;
            }
            actSuccess = shakeCtl(&shakeCtlData,opcode, 5000);    
        }
    }
    else if(pstActMsg->msgHead.actType == ACT_HEAT_CTL)
    {
        int chanNum = pstActMsg->msgHead.paramType;
        int isStart = 0;
        char * pData = (char *)pstActMsg->paramData;

        memcpy(&isStart,pData,sizeof(int));

        heatParam heatCtlParam;
        if(isStart)
        {
            heatCtlParam.opcode = CENTRE_START;
        }
        else
        {
            heatCtlParam.opcode = CENTRE_STOP;
        }

        pData += sizeof(int);
        memcpy(&heatCtlParam.temperature,pData,sizeof(int));

        printf("ACT_HEAT_CTL,temprature:%f,chan:%d\n",heatCtlParam.temperature,chanNum);

        heatCtlParam.chan = chanNum;

        if(pstActMsg->msgHead.moduleType == MODULE_SHAKE)
        {
            actSuccess = shakeCtl(&heatCtlParam,HEAT_CTL, 5000);
        }
        else if(pstActMsg->msgHead.moduleType == MODULE_QPCR1)
        {
            actSuccess = qpcrSubCtl(0,&heatCtlParam,HEAT_CTL, 5000);            
        }
        else if(pstActMsg->msgHead.moduleType == MODULE_QPCR2)
        {
            actSuccess = qpcrSubCtl(1,&heatCtlParam,HEAT_CTL, 5000);
        }

    }
    else if(pstActMsg->msgHead.actType == ACT_SCHEME_CTL)
    {
        int qpcrId = -1;
        if(pstActMsg->msgHead.moduleType == MODULE_QPCR1)
        {
            qpcrId = 0;
        }
        else if(pstActMsg->msgHead.moduleType == MODULE_QPCR2)
        {
            qpcrId = 1;
        }
        else
        {
            actSuccess = 0;
            qpcrId = -1;
        }
 
        if(qpcrId == -1)
        {
            actSuccess = 0; 
        }
        else
        {
            qpcrCtl qpcrCtlData;
            memset(&qpcrCtlData,0,sizeof(qpcrCtl));

            int opcodeTemp = CENTRE_START;
            int isStart = 0;
            memcpy(&isStart,pstActMsg->paramData,sizeof(int));
            
            if(isStart)
            {
                opcodeTemp = CENTRE_START; 
            }
            else
            {
                opcodeTemp = CENTRE_STOP;
            }
            qpcrCtlData.chanNum = 0xf0;
            actSuccess = qpcrSubCtl(qpcrId,&qpcrCtlData,opcodeTemp,2000);
        }     
         
    }
    else if(pstActMsg->msgHead.actType == ACT_LIGHT_CTL)
    {
        int chanNum = pstActMsg->msgHead.paramType;//light ctl opcode, 01 ,02
        char * pData = (char *)pstActMsg->paramData;
        int isStart = 0;
        memcpy(&isStart,pData,sizeof(int));
        

        if(pstActMsg->msgHead.moduleType == MODULE_QPCR1
           ||pstActMsg->msgHead.moduleType == MODULE_QPCR2 )
        {
            qpcrCtl qpcrCtlData;
            memset(&qpcrCtlData,0,sizeof(qpcrCtl));

            qpcrCtlData.paramDataI = isStart;
            int qpcrId = 0;
            if(pstActMsg->msgHead.moduleType == MODULE_QPCR1)
            {
                qpcrId = 0;
            }
            else 
            {
                qpcrId = 1;
            }
            qpcrCtlData.chanNum = chanNum;

            actSuccess = qpcrSubCtl(qpcrId,&qpcrCtlData,LIGHT_CTL,2000);
        }
    }
    else if(pstActMsg->msgHead.actType == ACT_MODULE_INIT)
    {
        if(pstActMsg->msgHead.moduleType == MODULE_SHAKE)
        {

            //1, leave all magnet;
            move_param moveParamArr[5];
            memset(&moveParamArr,0,sizeof(move_param)*5);
            int i = 0;
            for(i=0;i<5;i++)
            {
                moveParamArr[i].dec_speed = 8000;
                moveParamArr[i].inc_speed = 8000;
                moveParamArr[i].speed = 4000;
                moveParamArr[i].pos = 0;
                moveParamArr[i].sid = sidSmoothArr[i];
            }

            actSuccess = uimMoveAct_multi(moveParamArr,5,10000);

            //2, start all shake for 2 second;
            purifyCtl shakeCtlData;
            if(actSuccess == 1)
            {
                for(i=0;i<5;i++)
                {

                    shakeCtlData.chanNum = i;
                    shakeCtlData.paramType = PURIFY_SHAKE;              

                    shakeCtlData.duration = 2000; 

                    unsigned int opcode = CENTRE_START;
                    actSuccess = shakeCtl(&shakeCtlData,opcode, 5000);

                    if(actSuccess!=1)
                    {
                        printf("when init shake module, start shake failed,index:%d\n",i);
                        break;
                    }
                } 
            }           

 
        }
    }
    
    msgAckSock * pstResult = (msgAckSock *)actResultOut;
    
    printf("subboardActFunc, actSuccess:%d\n",actSuccess);
    if(!actSuccess)
    {        
        pstResult->status = 1;
    }
    else
    {
        pstResult->status = 0;
    }
}